import time,signal,os,sys,json

try:
    os.mkfifo('/tmp/server-50000')
except:
    pass
    
def send_msg(pid,msg,fp):
    try:
        #os.kill(pid,signal.SIGUSR1)
        fp.write( json.dumps( msg ) + '\n' )
        fp.flush()
        return True
    except:
        return False
client_list = []
def recv_msg(fp):
    try:
        msg = fp.readline()
        return json.loads(msg)
    except:
        global client_list
        for usr in client_list:
            if usr[2]==fp:
                os.remove(usr[3])
                client_list.remove(usr)
                fp.close()
        return None

def msg_server( ):
    import random
    p_server = open('/tmp/server-50000','r')
    global client_list
    print('loop start')
    n=0
    err = 0
    while True:
        try:
            msg = recv_msg( p_server )
            #print( msg )
            u = None
            if msg['type'] != 'r':
                auth = msg['from']
                for usr in client_list:
                    if usr[4] == auth:
                        u = usr
            else:
                print('user register')
                n += 1
                exist = False
                p_client = ''
                for u1 in client_list:
                    if u1[1]==msg['value']:
                        p_client = u1[2]
                        client_list.remove(u1)
                        exist = True
                p_name = '/tmp/client-%s' % (50000+msg['value'],)
                if not exist:
                    #print('client: %s'%p_name)
                    os.mkfifo(p_name)
                    os.kill(msg['value'],signal.SIGUSR1)
                    p_client = open(p_name,'w')
                auth_num = hash( '%s %s %s'%( msg['from'],msg['value'],random.random() ) )
                user1 = ( msg['from'], msg['value'],p_client,p_name,auth_num )
                client_list.append( user1 )
                u = user1
                msg =  {'type':'ctrl','from':'', 'to':msg['from'],'value':'hello','auth':auth_num}
                send_msg(user1[1],msg,p_client)
                print(n)
            if u is None:
                continue
            if msg['type'] is 'p':
                print('public message')
                for u1 in client_list:
                    msg['to'] = u1[0]
                    msg['from'] = u[0]
                    send_msg(u1[1], msg, u1[2])
                    print('msg:%s'%u1[0])
            elif msg['type'] is 'm':
                flag = False
                for u1 in client_list:
                    if u1[0]==msg['to']:
                        msg['from'] = u[0]
                        send_msg(u1[1], msg, u1[2])
                        flag = True
                if not flag:
                    send_msg(u[1], {'type':'ctrl','from':'', 'value':'notExist'}, u[2])
            elif msg['type']=='quit':
                for usr in client_list:
                    if usr[1]==msg['value']:
                        usr[2].close()
                        os.remove(usr[3])
                        client_list.remove(usr)
            elif msg['type']=='ctrl' and msg['value']=='quit':
                break
            elif msg['type']=='ctrl' and msg['value']=='users':
                users = []
                u = ''
                for usr in client_list:
                    users.append( usr[0] )
                    if usr[0]==msg['from']:
                        u = usr
                msg = {'type':'users', 'from':'', 'value':users }
                send_msg(u[1], msg, u[2])
        except Exception as e:
            #print('class:'+str(e.__class__))
            #print('string:'+str(e))
            p_server.close()
            p_server = open('/tmp/server-50000','r')
            
    print('msg_server exit\n')
    for u1 in client_list:
        print('USR: ',u1[0],u1[1])
        msg = {'type':'ctrl','from':'','value':'quit'}
        send_msg(u1[1],msg,u1[2])
        u1[2].close()
        os.remove(u1[3])
    p_server.close()
    os.remove('/tmp/server-50000')

#run in main process
msg_server( )
